package tagdb.denovo;

import com.compomics.util.experiment.identification.matches.ModificationMatch;
import tagdb.model.ModifiedPeptide;

import java.util.ArrayList;

import static tagdb.io.ModificationFile.getInvertedModIdMap;

/**
 * <b>DenovoHit</b>
 * <p>
 * This class represents the prediction information of one line in each spectrum from the pepnovo output.
 * </p>
 *
 * @author Thilo Muth
 */
public class DenovoHit {

    /**
     * The sequence/tag rank (starts at 0)
     */
    private int index;

    /**
     * The ranking score (the major score that is used)
     */
    private double rankScore;

    /**
     * The PepNovo score of the sequence
     */
    private double pepNovoScore;

    /**
     * The mass gap from the N-terminal to the start of the resources novo sequence.
     */
    private double nTermGap;

    /**
     * The mass gap from the C-terminal to the end of the resources novo sequence.
     */
    private double cTermGap;

    /**
     * M+H of the precursor.
     */
    private double precursorMh;

    /**
     * The ion charge.
     */
    private int charge;

    /**
     * The predicted amino acid sequence.
     */
    private String sequence;

    /**
     * The modified peptide sequence;
     */
    private ModifiedPeptide peptide = null;

    /**
     * Returns the peptide.
     * @return The peptide object
     */
    public ModifiedPeptide getPeptide() {
        if(peptide == null) convertHitToModifiedPeptide();
        return peptide;
    }

    /**
     * Converts hit to modified peptide.
     */
    private void convertHitToModifiedPeptide() {
        ArrayList<ModificationMatch> mods = new ArrayList<ModificationMatch>();

        String temp = "";
        String newSequence = "";
        int location = 0;
        int counter = -99;
        for(int i = 0; i < sequence.length(); i++) {
            Character letter = sequence.charAt(i) ;
            if(letter == '+') {
                location = i-1;
                temp += sequence.charAt(location);
                temp += letter;
                counter = 0;
            } else if(Character.isDigit(letter)) {
                temp += letter;
            } else {
                newSequence += letter;
                counter++;
                if(counter == 1) {
                    mods.add(new ModificationMatch(getInvertedModIdMap().get(temp), true, newSequence.lastIndexOf(letter)));
                    temp = "";
                }
            }
        }
        peptide = new ModifiedPeptide(newSequence, mods);
    }


    /**
     * Sets the modified peptide object.
     * @param peptide The modified peptide object.
     */
    public void setPeptide(ModifiedPeptide peptide) {
        this.peptide = peptide;
    }

    /**
     * Returns the index.
     * @return The index of the de novo hit.
     */
    public int getIndex() {
        return index;
    }

    /**
     * Sets the index of the de novo hit.
     * @param index The de novo hit index.
     */
    public void setIndex(int index) {
        this.index = index;
    }

    /**
     * Returns the rank score.
     * @return The rank score.
     */
    public double getRankScore() {
        return rankScore;
    }

    /**
     * Sets the rank score.
     * @param rankScore The rank score
     */
    public void setRankScore(double rankScore) {
        this.rankScore = rankScore;
    }

    /**
     * Returns the PepNovo score.
     * @return The PepNovo score.
     */
    public double getPepNovoScore() {
        return pepNovoScore;
    }

    /**
     * Sets the PepNovo score.
     * @param pepNovoScore The PepNovo score.
     */
    public void setPepNovoScore(double pepNovoScore) {
        this.pepNovoScore = pepNovoScore;
    }

    /**
     * Returns the n-terminal gap mass.
     * @return The n-terminal gap mass.
     */
    public double getNTermGap() {
        return nTermGap;
    }

    /**
     * Sets the n-terminal gap mass.
     * @param nTermGap The n-terminal gap mass.
     */
    public void setNTermGap(double nTermGap) {
        this.nTermGap = nTermGap;
    }

    /**
     * Returns the c-terminal gap mass.
     * @return The c-terminal gap mass.
     */
    public double getCTermGap() {
        return cTermGap;
    }

    /**
     * Sets the c-terminal gap mass.
     * @param cTermGap The c-terminal gap mass.
     */
    public void setCTermGap(double cTermGap) {
        this.cTermGap = cTermGap;
    }

    /**
     * Returns the precursor mass.
     * @return The precursor mass.
     */
    public double getPrecursorMh() {
        return precursorMh;
    }

    /**
     * Sets the precursor mass.
     * @param precursorMh The precursor mass.
     */
    public void setPrecursorMh(double precursorMh) {
        this.precursorMh = precursorMh;
    }

    /**
     * Returns the charge.
     * @return The ion charge.
     */
    public int getCharge() {
        return charge;
    }

    /**
     * Sets the charge.
     * @param charge The ion charge.
     */
    public void setCharge(int charge) {
        this.charge = charge;
    }

    /**
     * Returns the sequence.
     * @return The hit sequence.
     */
    public String getSequence() {
        return sequence;
    }

    /**
     * Sets the sequence.
     * @param sequence The hit sequence.
     */
    public void setSequence(String sequence) {
        this.sequence = sequence;
    }

    /**
     * Returns the length of the sequence.
     *
     * @return the length of the sequence
     */
    public int getLength() {
        return this.sequence.length();
    }
}
